package com.example.demo.sensitive.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.sensitive.dto.request.SensitiveWordRequest;
import com.example.demo.sensitive.dto.response.SensitiveWordResponse;
import com.example.demo.sensitive.entity.SensitiveWord;
import com.example.demo.sensitive.enums.SensitiveLevelEnum;
import com.example.demo.sensitive.mapper.SensitiveWordMapper;
import com.example.demo.sensitive.service.SensitiveWordService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName SensitiveWordServiceImpl
 * @Description 敏感词服务实现类
 * @Author System
 * @Date 2025/9/19
 **/
@Service
public class SensitiveWordServiceImpl extends ServiceImpl<SensitiveWordMapper, SensitiveWord> implements SensitiveWordService {

    @Override
    public Page<SensitiveWordResponse> getPageList(int current, int size, String category, Integer status, String keyword) {
        Page<SensitiveWord> page = new Page<>(current, size);
        Page<SensitiveWord> result = baseMapper.selectPageWithCondition(page, category, status, keyword);
        
        Page<SensitiveWordResponse> responsePage = new Page<>(current, size);
        responsePage.setRecords(result.getRecords().stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList()));
        responsePage.setTotal(result.getTotal());
        responsePage.setSize(result.getSize());
        responsePage.setCurrent(result.getCurrent());

        return responsePage;
    }

    @Override
    public SensitiveWordResponse getById(Long id) {
        SensitiveWord entity = baseMapper.selectById(id);
        if (entity == null) {
            throw new RuntimeException("敏感词不存在");
        }
        return convertToResponse(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long create(SensitiveWordRequest request) {
        // 检查敏感词是否已存在
        LambdaQueryWrapper<SensitiveWord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SensitiveWord::getWord, request.getWord());
        if (baseMapper.selectCount(wrapper) > 0) {
            throw new RuntimeException("敏感词已存在");
        }

        SensitiveWord entity = new SensitiveWord();
        BeanUtil.copyProperties(request, entity);
        entity.setCreateTime(LocalDateTime.now());
        entity.setUpdateTime(LocalDateTime.now());
        entity.setCreateBy(1L);
        
        baseMapper.insert(entity);
        return entity.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(Long id, SensitiveWordRequest request) {
        SensitiveWord entity = baseMapper.selectById(id);
        if (entity == null) {
            throw new RuntimeException("敏感词不存在");
        }

        // 检查敏感词是否已存在排除当前记录)
        LambdaQueryWrapper<SensitiveWord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SensitiveWord::getWord, request.getWord());
        wrapper.ne(SensitiveWord::getId, id);
        if (baseMapper.selectCount(wrapper) > 0) {
            throw new RuntimeException("敏感词已存在");
        }

        BeanUtil.copyProperties(request, entity);
        entity.setUpdateTime(LocalDateTime.now());
        entity.setUpdateBy(1L);
        
        baseMapper.updateById(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        SensitiveWord entity = baseMapper.selectById(id);
        if (entity == null) {
            throw new RuntimeException("敏感词不存在");
        }
        baseMapper.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchDelete(List<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return;
        }
        baseMapper.delete(new LambdaQueryWrapper<SensitiveWord>().in(SensitiveWord::getId, ids));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStatus(Long id, Integer status) {
        SensitiveWord entity = baseMapper.selectById(id);
        if (entity == null) {
            throw new RuntimeException("敏感词不存在");
        }
        entity.setStatus(status);
        entity.setUpdateTime(LocalDateTime.now());
        baseMapper.updateById(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchUpdateStatus(List<Long> ids, Integer status) {
        if (CollUtil.isEmpty(ids)) {
            return;
        }
        baseMapper.batchUpdateStatus(ids, status);
    }

    @Override
    public List<SensitiveWordResponse> getByCategory(String category) {
        List<SensitiveWord> entities = baseMapper.selectByCategory(category);
        return entities.stream().map(this::convertToResponse).collect(Collectors.toList());
    }

    @Override
    public List<SensitiveWordResponse> getEnabledWords() {
        List<SensitiveWord> entities = baseMapper.selectEnabledWords();
        return entities.stream().map(this::convertToResponse).collect(Collectors.toList());
    }

    @Override
    public List<CategoryStatistics> getCategoryStatistics() {
        List<SensitiveWordMapper.CategoryCount> counts = baseMapper.countByCategory();
        
        return counts.stream().map(count -> {
            CategoryStatistics stats = new CategoryStatistics();
            stats.setCategory(count.getCategory());
            stats.setCount(count.getCount());
            stats.setEnabledCount(count.getCount());
            return stats;
        }).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ImportResult batchImport(MultipartFile file) {
        ImportResult result = new ImportResult();
        result.setTotal(0);
        result.setSuccess(0);
        result.setFailed(0);
        result.setErrorMessages(new ArrayList<>());

        try {
            ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
            
            // 读取Excel数据
            List<List<Object>> data = reader.read();
            if (CollUtil.isEmpty(data)) {
                throw new RuntimeException("Excel文件为空");
            }

            // 跳过标题行
            for (int i = 1; i < data.size(); i++) {
                List<Object> row = data.get(i);
                if (CollUtil.isEmpty(row) || row.size() < 3) {
                    result.setFailed(result.getFailed() + 1);
                    result.getErrorMessages().add("第" + (i + 1) + "行数据格式错误");
                    continue;
                }

                try {
                    String word = String.valueOf(row.get(0)).trim();
                    String category = String.valueOf(row.get(1)).trim();
                    Integer level = Integer.parseInt(String.valueOf(row.get(2)));
                    String description = row.size() > 3 ? String.valueOf(row.get(3)) : "";

                    if (StrUtil.isBlank(word) || StrUtil.isBlank(category)) {
                        result.setFailed(result.getFailed() + 1);
                        result.getErrorMessages().add("第" + (i + 1) + "行敏感词或分类为空");
                        continue;
                    }

                    // 检查是否已存在
                    LambdaQueryWrapper<SensitiveWord> wrapper = new LambdaQueryWrapper<>();
                    wrapper.eq(SensitiveWord::getWord, word);
                    if (baseMapper.selectCount(wrapper) > 0) {
                        result.setFailed(result.getFailed() + 1);
                        result.getErrorMessages().add("第" + (i + 1) + "行敏感词已存在: " + word);
                        continue;
                    }

                    SensitiveWord entity = new SensitiveWord();
                    entity.setWord(word);
                    entity.setCategory(category);
                    entity.setLevel(level);
                    entity.setStatus(1);
                    entity.setEnableWildcard(0);
                    entity.setDescription(description);
                    entity.setCreateTime(LocalDateTime.now());
                    entity.setCreateBy(1L);

                    baseMapper.insert(entity);
                    result.setSuccess(result.getSuccess() + 1);

                } catch (Exception e) {
                    result.setFailed(result.getFailed() + 1);
                    result.getErrorMessages().add("第" + (i + 1) + "行处理失败: " + e.getMessage());
                }
            }

            result.setTotal(data.size() - 1); // 减去标题行

        } catch (Exception e) {
            throw new RuntimeException("导入失败: " + e.getMessage());
        }

        return result;
    }

    @Override
    public byte[] export(String category, Integer status) {
        LambdaQueryWrapper<SensitiveWord> wrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotBlank(category)) {
            wrapper.eq(SensitiveWord::getCategory, category);
        }
        if (status != null) {
            wrapper.eq(SensitiveWord::getStatus, status);
        }
        wrapper.orderByDesc(SensitiveWord::getCreateTime);

        List<SensitiveWord> entities = baseMapper.selectList(wrapper);

        try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            ExcelWriter writer = ExcelUtil.getWriter();
            
            // 写入标题
            writer.addHeaderAlias("word", "敏感词");
            writer.addHeaderAlias("category", "分类");
            writer.addHeaderAlias("level", "等级");
            writer.addHeaderAlias("description", "描述");
            writer.addHeaderAlias("createTime", "创建时间");

            // 写入数据
            writer.write(entities, true);
            writer.flush(out);
            
            return out.toByteArray();
        } catch (Exception e) {
            throw new RuntimeException("导出失败: " + e.getMessage());
        }
    }

    @Override
    public List<SensitiveWordResponse> getDefaultKeywords() {
        // 返回预设的默认敏感词库
        List<SensitiveWordResponse> defaultWords = new ArrayList<>();
        
        String[] categories = {"不文明词汇", "政治敏感", "违法违规", "商业敏感", "歧视言论", "网络暴力", "医疗违规"};
        for (String category : categories) {
            SensitiveWordResponse word = new SensitiveWordResponse();
            word.setCategory(category);
            word.setLevel(2);
            word.setLevelDesc("轻微");
            word.setStatus(1);
            word.setStatusDesc("启用");
            word.setDescription("默认" + category + "敏感词");
            defaultWords.add(word);
        }
        
        return defaultWords;
    }

    /**
     * 转换为响应对象
     */
    private SensitiveWordResponse convertToResponse(SensitiveWord entity) {
        SensitiveWordResponse response = new SensitiveWordResponse();
        BeanUtil.copyProperties(entity, response);
        
        // 设置等级描述和颜色
        SensitiveLevelEnum levelEnum = SensitiveLevelEnum.getByLevel(entity.getLevel());
        response.setLevelDesc(levelEnum.getDesc());
        response.setLevelColor(levelEnum.getColor());
        
        // 设置状态描述
        response.setStatusDesc(entity.getStatus() == 1 ? "启用" : "禁用");
        
        return response;
    }
}
